#ifndef TD_TILESET_H_
#define TD_TILESET_H_


/************************************************************************/
/* BOOST                                                                */
/************************************************************************/
#include "boost/smart_ptr/shared_ptr.hpp"

/************************************************************************/
/* STL                                                                  */
/************************************************************************/
#include <vector> 
#include <string>
#include <iostream>
#include <fstream>

/************************************************************************/
/* Core                                                                 */
/************************************************************************/
#include "Core/Color.h"
#include "Core/Utils.h"

/************************************************************************/
/* Resources                                                            */
/************************************************************************/
#include "Resources/Resource.h"
#include "Resources/Tiles/Tile.h"



using namespace std;
using namespace boost;

using namespace TD_Core;

namespace TD_Resources {

	class Tileset : public Resource {

	protected:
		
		/**Mapping info:*/
		Coord2D m_tileSize;
		Coord2D m_tileOffset;
		Coord2D m_numTiles;
	
		/**The tiles vector:*/
		vector<Tile *> m_tileVector;

		/**Clip matrix, used for defining the clips offsets in the tile set scheme*/
		SDL_Rect *m_clipMatrix;
		/**SDL image correspondent to the tiled image.*/
		shared_ptr<SDLImage> m_pTileImg; 
		
		/************************************************************************/
		/* Private functions                                                    */
		/************************************************************************/
		/*Loads the clip map for the tile set. Could vary the scheme according to
		 *a configuration file, for example.*/ 
		bool loadClipmap();
	
	public:
		
		enum {
			topLeft,
			topMiddle,
			topRight,
			middleLeft = 5,
			middleMiddle,
			middleRight,
			bottomLeft = 10,
			bottomMiddle,
			bottomRight
		} tileRelativePosition;

		enum {
			turretTopAndBottom,			
			turretTop,
			turretBottom,
			noTurret
		} turrets;
		
		/************************************************************************/
		/* Constructors                                                         */
		/************************************************************************/
		explicit Tileset();

		explicit Tileset(const Tileset &rhs);

		Tileset & operator=(const Tileset &rhs);

		//Initialization
		explicit Tileset(const string &tilesetName);

		~Tileset();

		/************************************************************************/
		/* Access functions                                                     */
		/************************************************************************/
		inline Tile * getTile(unsigned int index) const {
			if(index < m_tileVector.size()) {
				return(m_tileVector[index]);
			}
			return NULL;
		}

		inline const Coord2D & getTilesize() const {
			return(m_tileSize);
		}

		inline SDL_Rect * const getClippingMatrix() const {
			return(m_clipMatrix);
		}

		inline shared_ptr<SDLImage> getTileImg() const {
			return (m_pTileImg);
		}

		/************************************************************************/
		/* Functionalities                                                      */
		/************************************************************************/
		/**Could support different types of tile mapping:
		/* For instance, only supporting regular tileset algorithm
		*/
		bool loadTileset(const string &tilesetImgFile, unsigned int tileWidth, unsigned int tileHeight, const Color &keyColor);
		bool loadTileset(const string &tilesetImgFile, const Coord2D &tileSize, const Color &keyColor);

		bool loadCharacterTileset(const string &tilesetImgFile, unsigned int tileWidth, unsigned int tileHeight, const Color &keyColor);
		bool loadCharacterTileset(const string &tilesetImgFile, const Coord2D &tileSize, const Color &keyColor);

		/************************************************************************/
		/* Rendering                                                            */
		/************************************************************************/
		void render(SDL_Surface *g_destSurface, unsigned int deltaTime);

	};
}
#endif